package cn.maihe.elg.operation.config;

import cn.maihe.elg.operation.utils.ElgLogger;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Description
 * @Author caixh
 * @Date 2021/5/17.
 */
@EnableConfigurationProperties(ExecutorConfig.class)
@Configuration
@Slf4j
public class ExecutorConfigurations {
    @Autowired
    private ExecutorConfig executorConfig;


    // 通用
    @Bean("generalHandleExecutor")
    public ThreadPoolTaskExecutor generalHandleExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程池大小
        executor.setCorePoolSize(executorConfig.getGeneral().getCorePoolSize());
        // 最大线程数
        executor.setMaxPoolSize(executorConfig.getGeneral().getMaxPoolSize());
        // 队列容量
        executor.setQueueCapacity(executorConfig.getGeneral().getQueueCapacity());
        // 线程空闲时间
        executor.setKeepAliveSeconds(executorConfig.getGeneral().getKeepAliveSeconds());
        // 线程名字前缀
        if (StringUtils.isNotBlank(executorConfig.getGeneral().getThreadNamePrefix())) {
            executor.setThreadNamePrefix(executorConfig.getGeneral().getThreadNamePrefix());
        }
        // 拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }

    // 发票下载
    @Bean("invoiceDownLoadHandleExecutor")
    public ThreadPoolTaskExecutor invoiceDownLoadHandleExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程池大小
        executor.setCorePoolSize(executorConfig.getInvoiceDownLoad().getCorePoolSize());
        // 最大线程数
        executor.setMaxPoolSize(executorConfig.getInvoiceDownLoad().getMaxPoolSize());
        // 队列容量
        executor.setQueueCapacity(executorConfig.getInvoiceDownLoad().getQueueCapacity());
        // 线程空闲时间
        executor.setKeepAliveSeconds(executorConfig.getInvoiceDownLoad().getKeepAliveSeconds());
        // 线程名字前缀
        if (StringUtils.isNotBlank(executorConfig.getInvoiceDownLoad().getThreadNamePrefix())) {
            executor.setThreadNamePrefix(executorConfig.getInvoiceDownLoad().getThreadNamePrefix());
        }
        // 拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }

    // 结果通知
    @Bean("resultNoticeHandleExecutor")
    public ThreadPoolTaskExecutor resultNoticeHandleExecutor(){
        int corePoolSize = Runtime.getRuntime().availableProcessors() * 2;
        int maxPoolSize = corePoolSize * 2;
        ElgLogger.info(log, log -> log.info("resultNoticeHandleExecutor cpu corePoolSize:{};maximumPoolSize:{}", corePoolSize,maxPoolSize));

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程池大小
        if(executorConfig.getResultNotice().getCorePoolSize() == 0){
            executor.setCorePoolSize(corePoolSize);
        } else {
            executor.setCorePoolSize(executorConfig.getResultNotice().getCorePoolSize());
        }

        // 最大线程数
        if(executorConfig.getResultNotice().getMaxPoolSize() == 0){
            executor.setMaxPoolSize(maxPoolSize);
        } else {
            executor.setMaxPoolSize(executorConfig.getResultNotice().getMaxPoolSize());
        }
        ElgLogger.info(log, log -> log.info("resultNoticeHandleExecutor executor corePoolSize:{};maximumPoolSize:{}", executor.getCorePoolSize(),executor.getMaxPoolSize()));

        // 队列容量
        executor.setQueueCapacity(executorConfig.getResultNotice().getQueueCapacity());
        // 线程空闲时间
        executor.setKeepAliveSeconds(executorConfig.getResultNotice().getKeepAliveSeconds());
        // 线程名字前缀
        if (StringUtils.isNotBlank(executorConfig.getResultNotice().getThreadNamePrefix())) {
            executor.setThreadNamePrefix(executorConfig.getResultNotice().getThreadNamePrefix());
        }
        // 拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        // 初始化
        executor.initialize();
        return executor;
    }

    // 保函还原
    @Bean("guaranteeRestoreHandleExecutor")
    public ThreadPoolTaskExecutor guaranteeRestoreHandleExecutor(){
        int corePoolSize = Runtime.getRuntime().availableProcessors() * 2;
        int maxPoolSize = corePoolSize * 2;
        ElgLogger.info(log, log -> log.info("guaranteeRestoreHandleExecutor cpu corePoolSize:{};maximumPoolSize:{}", corePoolSize,maxPoolSize));

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程池大小
        if(executorConfig.getGuaranteeRestore().getCorePoolSize() == 0){
            executor.setCorePoolSize(corePoolSize);
        }else {
            executor.setCorePoolSize(executorConfig.getGuaranteeRestore().getCorePoolSize());
        }

        // 最大线程数
        if(executorConfig.getGuaranteeRestore().getMaxPoolSize() == 0){
            executor.setMaxPoolSize(maxPoolSize);
        }else {
            executor.setMaxPoolSize(executorConfig.getGuaranteeRestore().getMaxPoolSize());
        }
        ElgLogger.info(log, log -> log.info("guaranteeRestoreHandleExecutor executor corePoolSize:{};maximumPoolSize:{}", executor.getCorePoolSize(),executor.getMaxPoolSize()));

        // 队列容量
        executor.setQueueCapacity(executorConfig.getGuaranteeRestore().getQueueCapacity());
        // 线程空闲时间
        executor.setKeepAliveSeconds(executorConfig.getGuaranteeRestore().getKeepAliveSeconds());
        // 线程名字前缀
        if (StringUtils.isNotBlank(executorConfig.getGuaranteeRestore().getThreadNamePrefix())) {
            executor.setThreadNamePrefix(executorConfig.getGuaranteeRestore().getThreadNamePrefix());
        }
        // 拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        // 初始化
        executor.initialize();
        return executor;
    }
}
